/**
 * 此类用于定义主界面和主逻辑
 */

#ifndef FILERENAME_H
#define FILERENAME_H

#include "FRAdjustThread.h"
#include "FRDealPart.h"
#include "FRDealFile.h"
#include "FRFileInfo.h"
#include "FRHistory.h"
#include "FRModuleFactory.h"
#include "FRThreadPool.h"
#include "FRLineEdit.h"
#include "FRRadioButton.h"

#include <QMainWindow>
#include <QFile>
#include <QFileDialog>
#include <QStringList>
#include <QDebug>
#include <QTableWidget>
#include <QDesktopServices>
#include <QMessageBox>
#include <QAbstractButton>
#include <QIcon>
#include <QDir>
#include <QRadioButton>
#include <QSpinBox>
#include <QMenu>
#include <QAction>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QEvent>
#include <QMimeData>

#include <map>
#include <set>
#include <list>
#include <algorithm>
#include <type_traits>
#include <future>

QT_BEGIN_NAMESPACE
namespace Ui { class FileRename; }
QT_END_NAMESPACE

class FileRename : public QMainWindow
{
    Q_OBJECT

private:
    Ui::FileRename *ui;

    FRDealPart *m_pDealPart;
    FRAdjustThread *m_pAdjustThread;

    QValidator *m_pValidator;

    std::unique_ptr<FRThreadPool> m_upThreadPool;
    std::unique_ptr<FRModuleFactory> m_upModuleFactory;

    bool m_isDirRecursion;      // 递归添加文件
    bool m_isCaseInsensitivity; // 不区分大小写

private:
    /**
     * @brief 设置页面的初始状态
     */
    void SetInitStatus();

    /**
     * @brief 设置控件方法ID
     */
    void SetObjectMethod();

    /**
     * @brief 设置信号与槽连接
     */
    void SetObjectConnect();

    /**
     * @brief 添加文件信息
     * @param c_listFI
     * @param c_index
     */
    void InsertTW(const QList<FRFileInfo> &c_listFI, const int c_index = -1);

    /**
     * @brief 从tableWidget删除多行
     * @param c_listRow
     */
    void RemoveTWRows(const QList<int> &c_listRow);

    /**
     * @brief 获取选中的所有行
     * @return QList<int>
     */
    QList<int> GetSelectRows();

    /**
     * @brief 交换两行
     * @param c_iRowFirst
     * @param c_iRowSecond
     * @return bool
     */
    bool SwapRows(const int c_iRowFirst, const int c_iRowSecond);

    /**
     * @brief 获取文件对话框选中的文件或目录
     * @param fileMode
     * @return QStringList
     */
    QStringList GetFileDialogSelect(QFileDialog::FileMode fileMode = QFileDialog::ExistingFiles);

    /**
     * @brief 分析获取的文件对象
     * @param listSelect
     * @param listAnalyzeFI
     * @param isRecursion
     */
    void AnalyzeSelect(QList<QString> &listSelect, QList<FRFileInfo> &listAnalyzeFI, bool isRecursion = false);

    /**
     * @brief 处理重复的文件信息
     * @param listRealFI
     * @param listResultFI
     */
    void DealRepeatFI(QList<FRFileInfo> &listFI, QList<FRFileInfo> &listRealFI, QList<FRFileInfo> &listResultFI);

    /**
     * @brief 插入文件信息
     * @param c_listFI
     * @param c_index
     */
    void InsertFI(const QList<FRFileInfo> &c_listFI, const int c_index = -1);

    /**
     * @brief 修改
     * @param moduleParam
     */
    void Modify(FRModuleParam &moduleParam);

private slots:
    /**
     * @brief 打开文件
     */
    void on_actionOpenFiles_triggered();

    /**
     * @brief 打开文件夹
     */
    void on_actionOpenFolder_triggered();

    /**
     * @brief 清空所有文件
     */
    void on_actionClearAllFiles_triggered();

    /**
     * @brief 清空历史记录
     */
    void on_actionHistoryClear_triggered();

    /**
     * @brief 上一步的文件名
     */
    void on_actionPrevStep_triggered();

    /**
     * @brief 下一步的文件名
     */
    void on_actionNextStep_triggered();

    /**
     * @brief 刷新显示而不清空命令
     */
    void on_actionRefresh_triggered();

    /**
     * @brief 清空所有命令
     */
    void on_actionClearAllCommand_triggered();

    /**
     * @brief 确认更改
     */
    void on_actionSureModify_triggered();

    /**
     * @brief 是否递归添加文件
     */
    void on_actionDirRecursion_triggered();

    /**
     * @brief 是否忽略大小写
     */
    void on_actionCaseInsensitivity_triggered();

    /**
     * @brief 处理前缀后缀
     */
    void on_actionDealPart_triggered();

    /**
     * @brief 调整线程数
     */
    void on_actionAdjustThread_triggered();

    /**
     * @brief 打开源码地址
     */
    void on_actionCodeAddress_triggered();

    /**
     * @brief 打开关于软件
     */
    void on_actionAboutSoft_triggered();

    /**
     * @brief 拖动进入事件
     * @param event
     */
    void dragEnterEvent(QDragEnterEvent *event) override;

    /**
     * @brief 放下事件
     * @param event
     */
    void dropEvent(QDropEvent* event) override;

public:
    FileRename(QWidget *parent = nullptr);
    ~FileRename();

public slots:
    /**
     * @brief 更新列显示
     * @param c_type
     */
    void UpdateTWColumn(const int c_type);

    /**
     * @brief 更新按列排序
     * @param c_column
     */
    void UpdateSortTW(const int c_column);

    /**
     * @brief 更新恢复临时名称
     */
    void UpdateRefresh();

    /**
     * @brief 更新单选框
     */
    void UpdateRadioButton();

    /**
     * @brief 更新上下步
     */
    void UpdateStep();

    /**
     * @brief 更新历史信息
     */
    void UpdateHistory();

    /**
     * @brief 更新线程池线程数量
     * @param c_size
     */
    void UpdateThreadPoolSize(const int c_size);

    /**
     * @brief 右键打开菜单
     * @param c_point
     */
    void RightMenu(const QPoint &c_point);

    /**
     * @brief 添加模块
     */
    void UpdateAddition();

    /**
     * @brief 替换模块
     */
    void UpdateReplace();

    /**
     * @brief 编号模块
     */
    void UpdateNumber();

    /**
     * @brief 字母模块
     */
    void UpdateLetter();
};

#endif // FILERENAME_H
